# 导入相关库
import sys
import requests
from PyQt5 import QtWidgets
from PyQt5.QtCore import QThread, pyqtSignal
from PyQt5.QtWidgets import QMainWindow, QDialog, QLabel
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FC
from matplotlib import pyplot as plt

# 导入创建的主窗口python类
from mainwindow import Ui_MainWindow
from childwindow import Ui_Dialog

class MyDialog(QDialog):
    def __init__(self):
        QDialog.__init__(self)
        self.ui = Ui_Dialog()
        self.ui.setupUi(self)
        self.collectthread : CollectThread
        self.request : requests.Session
        self.rgb_red = 0
        self.rgb_green = 0
        self.rgb_blue = 0
        self.init_widget()
        self.initCharts()

    def initCharts(self):
        plt.rcParams['font.sans-serif'] = ['SimHei']
        self.fig = plt.figure()
        self.canvas = FC(self.fig)
        self.temp_axe = self.fig.add_subplot(221)
        self.humi_axe = self.fig.add_subplot(222)
        self.light_axe = self.fig.add_subplot(223)
        self.ui.verticalLayout.addWidget(self.canvas)

    def drawSinglelChart(self, axe, title, xlabel, ylabel, x, y):
        print(x)
        print(y)
        axe.cla()
        axe.plot(x, y, marker='o', color='green')
        axe.set_title(title)
        axe.set_xlabel(xlabel)
        axe.set_ylabel(ylabel)
        axe.set_xticks(x)
        axe.set_xticklabels(x, rotation=30)

    def getDatasByN(self, datas, apiTag : str, n : int):
        vals = datas[apiTag]['ResultObj']['DataPoints'][0]['PointDTO'][:n]
        vals.reverse()
        x = []
        y = []
        for dto in vals:
            x.append(dto['RecordTime'])
            y.append(dto['Value'])
        return x,y


    def init_widget(self):
        self.ui.horizontalSlider_red.valueChanged.connect(self.callback_Slider_value_change)
        self.ui.horizontalSlider_green.valueChanged.connect(self.callback_Slider_value_change)
        self.ui.horizontalSlider_blue.valueChanged.connect(self.callback_Slider_value_change)

    def callback_Slider_value_change(self):
        self.rgb_red = self.ui.horizontalSlider_red.value()
        self.rgb_green = self.ui.horizontalSlider_green.value()
        self.rgb_blue = self.ui.horizontalSlider_blue.value()
        self.ui.label_rgb_img.setStyleSheet("background-color: rgb({}, {}, {});".format(self.rgb_red, self.rgb_green, self.rgb_blue))
        self.collectthread.controls('983980', 'rgb_red', self.rgb_red)
        self.collectthread.controls('983980', 'rgb_green', self.rgb_green)
        self.collectthread.controls('983980', 'rgb_blue', self.rgb_blue)

    def init_collect(self, req : requests.Session):
        self.request = req
        self.collectthread = CollectThread(self.request)
        self.collectthread.ui_update_signal.connect(self.callback_ui_update)
        self.collectthread.start()

    def callback_ui_update(self, datas):
        val = datas['m_fan']['ResultObj']['Value']
        self.di_text_display(self.ui.label_fan_status ,val, "打开", "关闭")
        self.di_img_display(self.ui.label_fan_img, val, "fan_open.jpeg", "fan_close.jpeg")
        val = datas['m_smoke']['ResultObj']['Value']
        self.di_text_display(self.ui.label_smoke_status, val, "打开", "关闭")
        self.di_img_display(self.ui.label_smoke_img, val, "alarm_open.jpg", "alarm_close.jpg")
        val = datas['m_lamp']['ResultObj']['Value']
        self.di_text_display(self.ui.label_led_status, val, "打开", "关闭")
        self.di_img_display(self.ui.label_led_img, val, "led_open.jpeg", "led_close.jpeg")

        rgb = {
            'rgb_red': datas['rgb_red']['ResultObj']['Value'],
            'rgb_green': datas['rgb_green']['ResultObj']['Value'],
            'rgb_blue': datas['rgb_blue']['ResultObj']['Value']
        }
        print("当前颜色rgb({},{},{})".format(rgb['rgb_red'], rgb['rgb_green'], rgb['rgb_blue']))
        self.ui.label_rgb_text.setText("当前颜色rgb({},{},{})".format(rgb['rgb_red'], rgb['rgb_green'], rgb['rgb_blue']))

        x, y = self.getDatasByN(datas, 'm_temperature', 6)
        self.drawSinglelChart(self.temp_axe, "温度传感器", "时间", "温度值（℃）", x, y)
        x, y = self.getDatasByN(datas, 'm_temperature', 6)
        self.drawSinglelChart(self.humi_axe, "湿度传感器", "时间", "湿度值（%）",x ,y)
        x, y = self.getDatasByN(datas, 'm_temperature', 6)
        self.drawSinglelChart(self.light_axe, "光照度传感器", "时间", "光照值（Lux）",x,y)
        plt.tight_layout()
        self.canvas.draw()

    def di_text_display(self, label : QLabel, val, true_str, false_str):
        if val == 0:
            label.setText(false_str)
        else:
            label.setText(true_str)

    def di_img_display(self, label : QLabel, val, true_img, false_img):
        if val == 0:
            img = false_img
        else:
            img = true_img
        label.setStyleSheet('border-image: url(:/img/img/{});'.format(img))

class CollectThread(QThread):
    ui_update_signal = pyqtSignal(dict)
    def __init__(self, req : requests.Session):
        QThread.__init__(self)
        self.request = req
        self.apis = {
            'm_smoke' : 'http://api.nlecloud.com/devices/983980/sensors/m_smoke',
            'm_fan' : 'http://api.nlecloud.com/devices/983980/sensors/m_fan',
            'm_lamp' : 'http://api.nlecloud.com/devices/983980/sensors/m_lamp',
            'rgb_red':'http://api.nlecloud.com/devices/983980/sensors/rgb_red',
            'rgb_green': 'http://api.nlecloud.com/devices/983980/sensors/rgb_green',
            'rgb_blue': 'http://api.nlecloud.com/devices/983980/sensors/rgb_blue'
        }
        self.datas = {}
        self.api_cmd = "http://api.nlecloud.com/Cmds"


    def run(self):
        print("开始采集数据")
        while True:
            self.datas['m_smoke'] = self.get_single_val(self.apis['m_smoke'])
            self.datas['m_fan'] = self.get_single_val(self.apis['m_fan'])
            self.datas['m_lamp'] = self.get_single_val(self.apis['m_lamp'])
            self.datas['rgb_red'] = self.get_single_val(self.apis['rgb_red'])
            self.datas['rgb_green'] = self.get_single_val(self.apis['rgb_green'])
            self.datas['rgb_blue'] = self.get_single_val(self.apis['rgb_blue'])
            self.datas['m_temperature'] = self.collect_multi('983980', 'm_temperature', 1)
            self.datas['m_humidity'] = self.collect_multi('983980', 'm_humidity', 1)
            self.datas['m_light'] = self.collect_multi('983980', 'm_light', 1)
            self.ui_update_signal.emit(self.datas)
            self.sleep(3)

    def collect_multi(self, deviceId, apiTag, minago):
        get_params = {'ApiTags': apiTag, 'Method':1, 'TimeAgo':minago, 'Sort':'DESC'}
        api_multi = 'http://api.nlecloud.com/devices/{}/Datas'.format(deviceId)
        response = self.request.get(api_multi, params=get_params)
        if response.status_code == 200:
            print(response.json())
            if response.json()['Status'] == 0:
                return response.json()
            else:
                print(response.json())
        else:
            print(response)
        return ""


    def controls(self, deviceId, apiTag, val):
        post_params ={'deviceId': deviceId, 'apiTag': apiTag}
        response = self.request.post(self.api_cmd, params=post_params, json=val)
        if response.status_code == 200:
            print(response.json())
            if response.json()['Status'] == 0:
                return response.json()
            else:
                print(response.json())
        else:
            print(response)
        return ""

    def get_single_val(self, url):
        response = self.request.get(url)
        if response.status_code == 200:
            print(response.json())
            if response.json()['Status'] == 0:
                return response.json()
            else:
                print(response.json())
        else:
            print(response)
        return ""


class MyMainWindow(QMainWindow):
    '''
    自定义一个MyMainWindow类（继承了QMainWindow类）
    '''
    def __init__(self):
        '''
        初始化方法
        '''
        # 调用父类 `QMainWindow` 的初始化方法，确保父类的所有功能都被正确初始化。
        QMainWindow.__init__(self)
        # 创建一个 `Ui_MainWindow` 类的实例，并将其赋值给 `self.ui`。这个实例将用于设置窗口的界面
        self.ui = Ui_MainWindow()
        # 调用 `Ui_MainWindow` 实例的 `setupUi` 方法，并传入当前 `MyMainWindow` 类的实例作为参数。这个方法将设置窗口的属性和添加部件（如按钮、文本框等）。
        self.ui.setupUi(self)
        self.account : str
        self.password : str
        self.request = requests.Session()
        self.cwin : MyDialog
        self.init_widget()

    def init_widget(self):
        self.ui.pushButton.clicked.connect(self.clicked_login)

    def clicked_login(self):
        self.login_nlecloud()

    def login_nlecloud(self):
        self.account = self.ui.textEdit_account.toPlainText()
        self.password = self.ui.textEdit_password.toPlainText()
        print(self.account, "登录中")
        url = "https://api.nlecloud.com/Users/Login"
        login_data = {"Account" : self.account, "Password" : self.password}
        response = self.request.post(url=url, data=login_data)
        if response.status_code == 200:
            print(response.json())
            if response.json()['Status'] == 0:
                print('登录成功')
                accesstoken = response.json()['ResultObj']['AccessToken']
                headers = {'AccessToken':accesstoken}
                self.request.headers.update(headers)
                print(self.request.headers)
                self.show_childwindows()
            else:
                print("status", response.json())
        else:
            print(response)

    def show_childwindows(self):
        self.cwin = MyDialog()
        self.cwin.show()
        self.cwin.init_collect(self.request)

# 主程序入口
if __name__ == '__main__':
    # 创建一个 `QApplication` 对象。在 PyQt5 中，每个 GUI 应用程序都需要一个 `QApplication` 对象。`sys.argv` 是一个从命令行传递给 Python 脚本的参数列表。
    app = QtWidgets.QApplication(sys.argv)
    # 创建一个 `MyMainWindow` 类的实例。
    mainWin = MyMainWindow()
    # 显示窗口
    mainWin.show()
    # 进入应用程序的主事件循环。这个方法会等待，直到应用程序关闭，然后返回一个退出代码。`sys.exit()` 确保一个干净的退出，返回 `app.exec_()` 的结果。
    sys.exit(app.exec_())